package com.iteaj.iot.format;

import com.iteaj.iot.utils.ByteUtil;

/**
 * 数据格式转换
 * jvm默认使用大端, 所有数据以大端为基础
 */
public abstract class DataFormatConvert {

    /**
     * 从字节数组里面读取一个short类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public short readShort(byte[] bytes, int offset) {
        byte[] transform = byte2Transform(bytes, offset);
        return ByteUtil.bytesToShortOfReverse(transform, 0);
    }

    /**
     * 从字节数组里面读取一个无符号short类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public int readUShort(byte[] bytes, int offset) {
        return readShort(bytes, offset) & 0xFFFF;
    }

    /**
     * 将short类型转成字节数组
     * @param value
     * @return
     */
    public byte[] getBytes(short value) {
        byte[] bytes = ByteUtil.getBytesOfReverse(value);
        return byte2Transform(bytes, 0);
    }

    /**
     * 从字节数组里面读取一个int类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public int readInt(byte[] bytes, int offset) {
        byte[] transform = byte4Transform(bytes, offset);
        return ByteUtil.bytesToIntOfReverse(transform, 0);
    }

    /**
     * 从字节数组里面读取一个无符号short类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public long readUInt(byte[] bytes, int offset) {
        return readInt(bytes, offset) & 0xFFFFFFFFL;
    }

    /**
     * 将int类型转成字节数组
     * @param value
     * @return
     */
    public byte[] getBytes(int value) {
        return byte4Transform(ByteUtil.getBytesOfReverse(value), 0);
    }

    /**
     * 从字节数组里面读取一个long类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public long readLong(byte[] bytes, int offset) {
        byte[] transform = byte8Transform(bytes, offset);
        return ByteUtil.bytesToLongOfReverse(transform, 0);
    }

    /**
     * 将long类型转成字节数组
     * @param value
     * @return
     */
    public byte[] getBytes(long value) {
        return byte8Transform(ByteUtil.getBytesOfReverse(value), 0);
    }

    /**
     * 从字节数组里面读取一个无符号float类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public float readFloat(byte[] bytes, int offset) {
        return Float.intBitsToFloat(readInt(bytes, offset));
    }

    public byte[] getBytes(float value) {
        return byte4Transform(ByteUtil.getBytesOfReverse(value), 0);
    }

    /**
     * 从字节数组里面读取一个double类型数据
     * @param bytes 字节数据
     * @param offset 读取偏移
     * @return
     */
    public double readDouble(byte[] bytes, int offset) {
        return Double.longBitsToDouble(readLong(bytes, offset));
    }

    /**
     * 将double类型转成字节数组
     * @param value
     * @return
     */
    public byte[] getBytes(double value) {
        return byte8Transform(ByteUtil.getBytesOfReverse(value), 0);
    }

    /**
     * 两个字节的转换
     * @param data
     * @param offset
     * @return
     */
    protected abstract byte[] byte2Transform(byte[] data, int offset);

    /**
     * 四个字节的转换
     * @param data
     * @param offset
     * @return
     */
    protected abstract byte[] byte4Transform(byte[] data, int offset);

    /**
     * 8个字节的转换
     * @param data
     * @param offset
     * @return
     */
    protected abstract byte[] byte8Transform(byte[] data, int offset);

    /**
     * 获取数据格数转换器
     * @param format
     * @return
     */
    public static DataFormatConvert getInstance(DataFormat format) {
        switch (format) {
            case ABCD: return ABCDFormat.INSTANCE;
            case BADC: return BADCFormat.INSTANCE;
            case DCBA: return DCBAFormat.INSTANCE;
            case CDAB: return CDABFormat.INSTANCE;
            default: throw new IllegalArgumentException("不支持的格式类型["+format+"]");
        }
    }
}
